package net.pws.oos.biz.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import net.pws.common.event.ApplicationEventBus;
import net.pws.common.event.ApplicationEventListener;
import net.pws.common.event.ApplicationEventObject;
import net.pws.common.util.DateUtils;
import net.pws.oos.biz.event.CheckinExcelExportFailedEventObject;
import net.pws.oos.biz.event.CheckinExcelExportSucceedEventObject;
import net.pws.oos.biz.event.NoticeCreatedEventObject;
import net.pws.oos.biz.event.NoticeReadEventObject;
import net.pws.oos.biz.event.TaskExcelExportFailedEventObject;
import net.pws.oos.biz.event.TaskExcelExportSucceedEventObject;
import net.pws.oos.biz.model.Message;
import net.pws.oos.biz.model.Notice;
import net.pws.oos.biz.model.User;
import net.pws.oos.biz.query.MessageFinder;
import net.pws.oos.biz.query.parameter.MessageQueryParameter;
import net.pws.oos.biz.service.MessageService;
import net.pws.oos.biz.service.export.CheckinExcelExportData;
import net.pws.oos.biz.service.export.TaskExcelExportData;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class DefaultMessageService extends AbstractService implements
                                                          MessageService,
                                                          ApplicationEventListener,
                                                          InitializingBean {
    
    @Autowired
    private MessageFinder messageFinder;
    
    @Override
    public Message save(Message message) {
        entityManager.persist(message);
        return message;
    }
    
    @Override
    public void read(Message message) {
        if (message == null) {
            return;
        }
        if (message.isRead()) {
            return;
        }
        
        message.setRead(true);
        message.setReadTime(new Date());
        entityManager.persist(message);
    }
    
    @Override
    public void afterPropertiesSet() throws Exception {
        ApplicationEventBus.getInstance().addListener(this);
    }
    
    @Override
    public boolean support(ApplicationEventObject event) {
        if (event instanceof NoticeCreatedEventObject) {
            return true;
        }
        if (event instanceof NoticeReadEventObject) {
            return true;
        }
        if (event instanceof TaskExcelExportSucceedEventObject) {
            return true;
        }
        if (event instanceof TaskExcelExportFailedEventObject) {
            return true;
        }
        if (event instanceof CheckinExcelExportSucceedEventObject) {
            return true;
        }
        if (event instanceof CheckinExcelExportFailedEventObject) {
            return true;
        }
        return false;
    }
    
    @Override
    public void handle(ApplicationEventObject event) {
        if (event instanceof NoticeCreatedEventObject) {
            handleNoticeCreated((NoticeCreatedEventObject) event);
        }
        else if (event instanceof NoticeReadEventObject) {
            handleNoticeReadEvent((NoticeReadEventObject) event);
        }
        else if (event instanceof TaskExcelExportSucceedEventObject) {
            handleTaskExcelSucceedEvent((TaskExcelExportSucceedEventObject) event);
        }
        else if (event instanceof TaskExcelExportFailedEventObject) {
            handleTaskExcelFailedEvent((TaskExcelExportFailedEventObject) event);
        }
        else if (event instanceof CheckinExcelExportSucceedEventObject) {
            handleCheckinExcelSucceedEvent((CheckinExcelExportSucceedEventObject) event);
        }
        else if (event instanceof CheckinExcelExportFailedEventObject) {
            handleCheckinExcelFailedEvent((CheckinExcelExportFailedEventObject) event);
        }
    }
    
    private void handleNoticeCreated(NoticeCreatedEventObject event) {
        List<Message> messages = new ArrayList<Message>();
        Date createTime = new Date();
        Notice notice = event.getNotice();
        String name = "通知：" + notice.getName();
        String url = Message.URL_NOTICE + notice.getId();
        for (User user : event.getUsers()) {
            Message message = new Message();
            message.setCreateTime(createTime);
            message.setName(name);
            message.setUrl(url);
            message.setUserId(user.getId());
            messages.add(message);
        }
        entityManager.save(messages);
    }
    
    private void handleNoticeReadEvent(NoticeReadEventObject event) {
        MessageQueryParameter queryParameter = new MessageQueryParameter();
        queryParameter.setRead(Boolean.FALSE);
        queryParameter.setUserId(event.getUserId());
        queryParameter.setUrl(Message.URL_NOTICE + event.getNoticeId());
        Message message = messageFinder.findOne(queryParameter);
        if (message != null) {
            read(message);
        }
    }
    
    private void handleTaskExcelSucceedEvent(TaskExcelExportSucceedEventObject event) {
        TaskExcelExportData data = event.getData();
        Message message = new Message();
        message.setCreateTime(new Date());
        StringBuilder name = new StringBuilder("导出通知：您于");
        name.append(DateUtils.getDateTimeStr(data.getCreateTime()));
        name.append("开始的导出任务已成功，请点击下载文件");
        message.setName(name.toString());
        message.setUrl(data.getExcelUri());
        message.setUserId(data.getUserId());
        save(message);
    }
    
    private void handleTaskExcelFailedEvent(TaskExcelExportFailedEventObject event) {
        TaskExcelExportData data = event.getData();
        Message message = new Message();
        message.setCreateTime(new Date());
        message.setUserId(data.getUserId());
        
        StringBuilder name = new StringBuilder("导出通知：您于");
        name.append(DateUtils.getDateTimeStr(data.getCreateTime()));
        name.append("开始的导出任务已失败");
        message.setName(name.toString());
        
        StringBuilder desc = new StringBuilder("您于");
        name.append(DateUtils.getDateStr(data.getCreateTime()));
        name.append("开始的导出任务已失败，请重试。如果已经失败多次，请联系系统管理员处理。");
        message.setDescription(desc.toString());
        
        save(message);
    }
    
    private void handleCheckinExcelSucceedEvent(CheckinExcelExportSucceedEventObject event) {
    	CheckinExcelExportData data = event.getData();
        Message message = new Message();
        message.setCreateTime(new Date());
        StringBuilder name = new StringBuilder("导出通知：您于");
        name.append(DateUtils.getDateTimeStr(data.getCreateTime()));
        name.append("开始的导出任务已成功，请点击下载文件");
        message.setName(name.toString());
        message.setUrl(data.getExcelUri());
        message.setUserId(data.getUserId());
        save(message);
		
	}
    
    private void handleCheckinExcelFailedEvent(
			CheckinExcelExportFailedEventObject event) {
    	CheckinExcelExportData data = event.getData();
        Message message = new Message();
        message.setCreateTime(new Date());
        message.setUserId(data.getUserId());
        
        StringBuilder name = new StringBuilder("导出通知：您于");
        name.append(DateUtils.getDateTimeStr(data.getCreateTime()));
        name.append("开始的导出任务已失败");
        message.setName(name.toString());
        
        StringBuilder desc = new StringBuilder("您于");
        name.append(DateUtils.getDateStr(data.getCreateTime()));
        name.append("开始的导出任务已失败，请重试。如果已经失败多次，请联系系统管理员处理。");
        message.setDescription(desc.toString());
        
        save(message);
		
	}
}
